#include <boost/weak_ptr.hpp>


namespace PimplImplementation
{
	template<typename T>
	class Shared_ptr_Impl;

template<typename T>
class Weak_ptr_Impl
{
	template<typename T>
	friend class PimplImplementation::Shared_ptr_Impl;
	template<typename Y>
	friend class Weak_ptr_Impl;

public:
	Weak_ptr_Impl()
		: m_ptr()
	{

	}

	Weak_ptr_Impl( const Weak_ptr_Impl<T>& o )
		: m_ptr( o.m_ptr )
	{

	}

	// there is no other possibility to type convert a weak pointer from T To Y
	// by temporarily convert it to a shared_ptr.... huh?!
	template<typename Y>
	Weak_ptr_Impl( const Weak_ptr_Impl<Y>& o )
		: m_ptr( boost::static_pointer_cast<T>(boost::shared_ptr<Y>( o.m_ptr ) ) )
	{

	}

	Weak_ptr_Impl( const PimplImplementation::Shared_ptr_Impl<T>& o )
		: m_ptr( o.m_ptr )
	{

	}

	template<typename Y>
	Weak_ptr_Impl( const PimplImplementation::Shared_ptr_Impl<Y>& o )
		: m_ptr( boost::static_pointer_cast<T>( o.m_ptr ) )
	{

	}

	long UseCount() const
	{
		return m_ptr.use_count();
	}

	bool Expired() const
	{
		return m_ptr.expired();
	}

	bool Empty() const
	{
		return m_ptr._empty();
	}

	void Reset()
	{
		m_ptr.reset();
	}

	const Weak_ptr_Impl<T>& operator=( const Weak_ptr_Impl<T>& rhs )
	{
		m_ptr = rhs.m_ptr;
		return *this;
	}

	const Weak_ptr_Impl<T>& operator=( const PimplImplementation::Shared_ptr_Impl<T>& rhs )
	{
		m_ptr = rhs.m_ptr;
		return *this;
	}

private:
	boost::weak_ptr<T>		m_ptr;
};

}
